<?php
namespace app\index\controller;

use think\worker\Server;
use Workerman\Lib\Timer;

class Worker extends Server
{
    protected $socket = 'websocket://workman_tp5.com:2346';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        //$connection->send('我收到你的信息了');
        global $worker;
        // 新增加一个属性，用来保存uid到connection的映射(uid是用户id或者客户端唯一标识)
        if(!isset($worker->uidConnections))
        {
            $worker->uidConnections = array();
        }
        // 判断当前客户端是否已经验证,即是否设置了uid
        if(!isset($connection->uid))
        {
            // 没验证的话把第一个包当做uid（这里为了方便演示，没做真正的验证）
            $connection->uid = $data;
            /* 保存uid到connection的映射，这样可以方便的通过uid查找connection，
             * 实现针对特定uid推送数据
             */
            $worker->uidConnections[$connection->uid] = $connection;
            return $connection->send('login success, your uid is ' . $connection->uid);
        }
        // 其它逻辑，针对某个uid发送 或者 全局广播
        // 假设消息格式为 uid:message 时是对 uid 发送 message
        // uid 为 all 时是全局广播
        list($recv_uid, $message) = explode(':', $data);
        // 全局广播
        if($recv_uid == 'all')
        {
            $this->broadcast($message);
        }
        // 给特定uid发送
        else
        {
            $this->sendMessageByUid($recv_uid, $message);
        }
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        global $worker;
        if(isset($connection->uid))
        {
            // 连接断开时删除映射
            unset($worker->uidConnections[$connection->uid]);
        }
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {
//        Timer::add(10, function()use($worker){
//            foreach($worker->connections as $connection) {
//                $connection->send('这个是定时发送！');
//            }
//        });
    }

    // 向所有验证的用户推送数据
    public function broadcast($message)
    {
        global $worker;
        foreach($worker->uidConnections as $connection)
        {
            $connection->send($message);
        }
    }

    // 针对uid推送数据
    public function sendMessageByUid($uid, $message)
    {
        global $worker;
        if(isset($worker->uidConnections[$uid]))
        {
            $connection = $worker->uidConnections[$uid];
            $connection->send($message);
        }
    }
}
